﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace Common.Jwt.Extensions
{
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 添加Jwt服务
        /// </summary>
        /// <param name="services"></param> 
        /// <returns></returns>
        public static IServiceCollection AddJwtService(this IServiceCollection services, string section = "JwtConfig")
        {
            var jwtConfig = ServiceProviderServiceExtensions.GetRequiredService<IConfiguration>(services.BuildServiceProvider()).GetSection(section).Get<JwtConfig>();
            JwtConfig.Init(jwtConfig);
            //var authenticationProviderKey = "Decen";
            services.AddAuthentication(option =>
                {
                    //认证middleware配置
                    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                    //option.DefaultAuthenticateScheme = authenticationProviderKey;
                    //option.DefaultChallengeScheme = authenticationProviderKey;
                })
               .AddJwtBearer(options =>
               {
                   options.TokenValidationParameters = new TokenValidationParameters
                   {
                       //Token颁发机构
                       ValidIssuer = JwtConfig.Instance.Issuer,
                       //颁发给谁
                       ValidAudience = JwtConfig.Instance.Audience,
                       //这里的key要进行加密
                       IssuerSigningKey = JwtConfig.Instance.SymmetricSecurityKey,
                       //是否验证Token有效期，使用当前时间与Token的Claims中的NotBefore和Expires对比
                       ValidateLifetime = true,
                       ValidateIssuer = true,
                       ValidateAudience = true,
                       ValidateIssuerSigningKey = true,
                       //注意这是缓冲过期时间，总的有效时间等于这个时间加上jwt的过期时间，如果不配置，默认是5分钟
                       ClockSkew = TimeSpan.FromSeconds(4)
                   };
               });
            ////全局鉴权
            //services.AddAuthorization(options =>
            //{
            //    options.FallbackPolicy = new AuthorizationPolicyBuilder()
            //        .RequireAuthenticatedUser()
            //        .Build();
            //});
            //只有控制器进行鉴权
            services.AddControllers(options =>
            {
                options.Filters.Add(new AuthorizeFilter()); // 添加全局授权过滤器
            });

            return services;
        }

        /// <summary>
        /// Swagger添加Jwt功能
        /// </summary>
        /// <param name="options"></param>
        public static SwaggerGenOptions SwaggerAddJwtHeader(this SwaggerGenOptions options)
        {
            options.AddSecurityRequirement(new OpenApiSecurityRequirement()
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer",
                        }
                    },
                new string[] { }
                }
            });
            options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = "JWT授权(数据将在请求头中进行传输) 在下方输入Bearer {token} 即可，注意两者之间有空格",
                Name = "Authorization",//jwt默认的参数名称
                In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
                Type = SecuritySchemeType.ApiKey,
                BearerFormat = "JWT",
                Scheme = "Bearer"
            });
            return options;
        }

    }
}
